import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useState,} from 'react';
import {Tree} from 'antd';
import {GTreeProps} from './TreeProps';
import {DataNode, EventDataNode, Key} from 'rc-tree/lib/interface';
import {request} from "../Request";

export const GTree = forwardRef((props: GTreeProps, ref: any) => {
  const [data, setData] = useState<any[]>(
    props.root
      ? [
        {
          title: props.root[props.data?.textField || 'name'],
          key: props.root[props.data?.valueField || 'id'],
          data: props.root,
        },
      ]
      : [],
  );
  const [selection, setSelection] = useState<{
    selectedKeys: Key[];
    selectedNodes: DataNode[];
  }>({
    selectedKeys: [],
    selectedNodes: [],
  });

  const updateTreeData = (
    list: any[],
    key: React.Key,
    children: any[],
  ): any[] => {
    return list.map((node) => {
      if (node.key === key) {
        return {
          ...node,
          children,
        };
      }
      if (node.children) {
        return {
          ...node,
          children: updateTreeData(node.children, key, children),
        };
      }
      return node;
    });
  };

  const loadData = useCallback((node: any): Promise<any> => {
    if (node?.children) {
      return Promise.resolve(node.children);
    } else {
      return request<any[]>(props.url + (node?.key || ''), {
        method: 'get',
        errMsg: '获取数据错误'
      }).then(resp => {
        let newNode: any;
        const children = resp.map((value: any) => {
          return {
            title: value[props.data?.textField || 'name'],
            key: value[props.data?.valueField || 'id'],
            data: value,
          };
        });
        setData((origin) => {
          if (node) {
            newNode = updateTreeData(origin, node.key, children);
          } else {
            newNode = children;
          }
          return newNode;
        });
        return newNode;
      });
    }
  }, []);

  const onSelect = useCallback((
    selectedKeys: Key[],
    info: {
      event: 'select';
      selected: boolean;
      node: EventDataNode<DataNode>;
      selectedNodes: DataNode[];
      nativeEvent: MouseEvent;
    },
  ) => {
    const newValue = {
      selectedKeys: selectedKeys,
      selectedNodes: info.selectedNodes,
    };
    setSelection(newValue);
    props.onSelected?.(newValue);
    props.onSelect?.(selectedKeys, info);
  }, []);

  useImperativeHandle(
    ref,
    () => ({
      selection: selection,
      reloadSelectedNode: () => {
        selection.selectedNodes?.forEach((node) => {
          node.children = undefined;
          loadData(node);
        });
      },
    }),
    [selection],
  );

  useEffect(() => {
    loadData(props.root).then((node: any[]) => {
      if (node?.length > 0) {
        onSelect([node[0].key], {
          event: 'select',
          selected: true,
          node: node[0],
          selectedNodes: [node[0]],
          nativeEvent: new MouseEvent(null as any, null as any),
        });
      }
    });
  }, []);

  return (
    <Tree
      loadData={loadData}
      treeData={data}
      {...props}
      selectedKeys={selection.selectedKeys}
      onSelect={onSelect}
    />
  );
});
